package com.xyht.sca_s.student_manage_system.modules.trainingSchool.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.xyht.sca_s.student_manage_system.common.commonReturn.CommonCodeEnum;
import com.xyht.sca_s.student_manage_system.common.commonReturn.CommonResult;
import com.xyht.sca_s.student_manage_system.common.commonReturn.ExceptionCast;
import com.xyht.sca_s.student_manage_system.common.commonReturn.ResponseResult;
import com.xyht.sca_s.student_manage_system.modules.trainingSchool.entity.*;
import com.xyht.sca_s.student_manage_system.modules.trainingSchool.entity.req.SmsTsChargeItemAmountReq;
import com.xyht.sca_s.student_manage_system.modules.trainingSchool.entity.resp.SmsTsChargeItemAmountResp;
import com.xyht.sca_s.student_manage_system.modules.trainingSchool.mapper.*;
import com.xyht.sca_s.student_manage_system.modules.trainingSchool.service.SmsTsChargeItemAmountService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

import static com.xyht.sca_s.student_manage_system.common.util.ParamCheckUtil.isNullOrEmpty;

/**
 * <p>
 * 收费项金额表 服务实现类
 * </p>
 *
 * @author XYHT
 * @since 2024-05-16
 */
@Service
public class SmsTsChargeItemAmountServiceImpl extends ServiceImpl<SmsTsChargeItemAmountMapper, SmsTsChargeItemAmount> implements SmsTsChargeItemAmountService {

    @Resource
    private SmsTsFeeCategoryMapper smsTsFeeCategoryMapper;
    @Resource
    private SmsTsWorkerLevelMapper smsTsWorkerLevelMapper;
    @Resource
    private SmsTsChargeItemMapper smsTsChargeItemMapper;
    @Resource
    private SmsTsJobMapper smsTsJobMapper;

    @Override
    @Transactional
    public ResponseResult add(SmsTsChargeItemAmountReq req) {
        if (isNullOrEmpty(req.getCategoryId(), req.getLevelId(), req.getItemIdList(), req.getAmountList())) {
            return CommonResult.failed(CommonCodeEnum.INVALID_PARAM);
        }

        SmsTsFeeCategory category = smsTsFeeCategoryMapper.selectById(req.getCategoryId());
        if (category == null) {
            return CommonResult.failed(CommonCodeEnum.SCHOOL_TRAINING_FEE_CATEGORY_NOT_EXIST);
        }

        SmsTsWorkerLevel level = smsTsWorkerLevelMapper.selectById(req.getLevelId());
        if (level == null) {
            return CommonResult.failed(CommonCodeEnum.SCHOOL_TRAINING_WORKER_LEVEL_NOT_EXIST);
        }

        int itemListSize = req.getItemIdList().size();
        if (itemListSize != req.getAmountList().size()) {
            return CommonResult.failed(CommonCodeEnum.INVALID_PARAM);
        }

        boolean flag = false;
        if (!req.getDescriptionList().isEmpty()) {
            flag = true;
            if (itemListSize != req.getDescriptionList().size()) {
                return CommonResult.failed(CommonCodeEnum.INVALID_PARAM);
            }
        }

        List<SmsTsChargeItemAmount> itemAmountList = new ArrayList<>();
        for (int i = 0; i < itemListSize; i++) {
            String itemId = req.getItemIdList().get(i);
            SmsTsChargeItem item = smsTsChargeItemMapper.selectById(itemId);
            if (item == null) {
                return CommonResult.failed(CommonCodeEnum.SCHOOL_TRAINING_CHARGE_ITEM_NOT_EXIST);
            }

            // 校验是否有数据重复
            SmsTsChargeItemAmount itemAmount = this.getOne(new LambdaQueryWrapper<SmsTsChargeItemAmount>()
                    .eq(SmsTsChargeItemAmount::getCategoryId, req.getCategoryId())
                    .eq(SmsTsChargeItemAmount::getLevelId, req.getLevelId())
                    .eq(SmsTsChargeItemAmount::getItemId, itemId));
            if (itemAmount != null) {
                ExceptionCast.cast(CommonResult.failed(CommonCodeEnum.DATA_EXIST));
            }

            itemAmount = new SmsTsChargeItemAmount();
            BeanUtils.copyProperties(req, itemAmount);
            itemAmount.setItemId(itemId);
            itemAmount.setAmount(req.getAmountList().get(i));
            if (flag) {
                itemAmount.setDescription(req.getDescriptionList().get(i));
            }
            itemAmountList.add(itemAmount);
        }
        this.saveBatch(itemAmountList);

        return CommonResult.success();
    }

    @Override
    @Transactional
    public ResponseResult update(SmsTsChargeItemAmountReq req) {
        if (isNullOrEmpty(req.getIdList(), req.getAmountList())) {
            return CommonResult.failed(CommonCodeEnum.INVALID_PARAM);
        }

        int idListSize = req.getIdList().size();
        if (idListSize != req.getAmountList().size()) {
            return CommonResult.failed(CommonCodeEnum.INVALID_PARAM);
        }

        boolean flag = false;
        if (!req.getDescriptionList().isEmpty()) {
            flag = true;
            if (idListSize != req.getDescriptionList().size()) {
                return CommonResult.failed(CommonCodeEnum.INVALID_PARAM);
            }
        }

        List<SmsTsChargeItemAmount> itemAmountList = this.listByIds(req.getIdList());
        if (itemAmountList.size() != idListSize) {
            return CommonResult.failed(CommonCodeEnum.SCHOOL_TRAINING_CHARGE_ITEM_AMOUNT_NOT_EXIST);
        }

        for (int i = 0; i < idListSize; i++) {
            SmsTsChargeItemAmount itemAmount = itemAmountList.get(i);
            itemAmount.setAmount(req.getAmountList().get(i));
            if (flag) {
                itemAmount.setDescription(req.getDescriptionList().get(i));
            }
        }
        this.updateBatchById(itemAmountList);

        return CommonResult.success();
    }

    @Override
    public ResponseResult detail(String categoryId, String levelId) {
        List<SmsTsChargeItemAmount> itemAmountList = this.list(new LambdaQueryWrapper<SmsTsChargeItemAmount>()
                .eq(SmsTsChargeItemAmount::getCategoryId, categoryId)
                .eq(SmsTsChargeItemAmount::getLevelId, levelId));
        if (itemAmountList.isEmpty()) {
            return CommonResult.failed(CommonCodeEnum.SCHOOL_TRAINING_CHARGE_ITEM_AMOUNT_NOT_EXIST);
        }

        List<SmsTsChargeItem> itemList = smsTsChargeItemMapper.selectList(new LambdaQueryWrapper<SmsTsChargeItem>()
                .orderByAsc(SmsTsChargeItem::getId));

        // 把原始的list放入map
        Map<String, SmsTsChargeItemAmount> map = new HashMap<>();
        for (SmsTsChargeItemAmount itemAmount : itemAmountList) {
            map.put(itemAmount.getItemId(), itemAmount);
        }

        // 按照itemList的顺序创建排序后的itemAmountList
        List<SmsTsChargeItemAmount> sortedItemAmountList = new ArrayList<>();
        for (SmsTsChargeItem item : itemList) {
            // 检查是否存在对应的item，若存在则添加到sortedItemList
            SmsTsChargeItemAmount itemAmount = map.get(item.getId());
            sortedItemAmountList.add(itemAmount);
        }

        List<SmsTsChargeItemAmountResp> collect = sortedItemAmountList.stream().map(itemAmount -> {
            SmsTsChargeItemAmountResp resp = new SmsTsChargeItemAmountResp();
            BeanUtils.copyProperties(itemAmount, resp);
            SmsTsFeeCategory category = smsTsFeeCategoryMapper.selectById(itemAmount.getCategoryId());
            if (category != null) {
                resp.setCategoryName(category.getName());
            }

            SmsTsWorkerLevel level = smsTsWorkerLevelMapper.selectById(itemAmount.getLevelId());
            if (level != null) {
                resp.setLevelName(level.getName());
            }

            SmsTsChargeItem filterItem = itemList.stream().filter(item -> item.getId().equals(itemAmount.getItemId())).collect(Collectors.toList()).get(0);
            if (filterItem != null) {
                resp.setItemName(filterItem.getName());
            }

            return resp;
        }).collect(Collectors.toList());

        return CommonResult.success(collect, collect.size());
    }

    @Override
    public ResponseResult list(String jobId, String levelId) {
        SmsTsJob job = smsTsJobMapper.selectById(jobId);
        if (job == null) {
            return CommonResult.failed(CommonCodeEnum.SCHOOL_TRAINING_JOB_NOT_EXIST);
        }

        SmsTsWorkerLevel level = smsTsWorkerLevelMapper.selectById(levelId);
        if (level == null) {
            return CommonResult.failed(CommonCodeEnum.SCHOOL_TRAINING_WORKER_LEVEL_NOT_EXIST);
        }

        List<SmsTsChargeItemAmount> itemAmountList = this.list(new LambdaQueryWrapper<SmsTsChargeItemAmount>()
                .eq(SmsTsChargeItemAmount::getCategoryId, job.getCategoryId())
                .eq(SmsTsChargeItemAmount::getLevelId, levelId));
        if (itemAmountList.isEmpty()) {
            return CommonResult.failed(CommonCodeEnum.SCHOOL_TRAINING_CHARGE_ITEM_AMOUNT_NOT_EXIST);
        }

        List<SmsTsChargeItem> itemList = smsTsChargeItemMapper.selectList(new LambdaQueryWrapper<SmsTsChargeItem>()
                .orderByAsc(SmsTsChargeItem::getId));

        // 把原始的list放入map
        Map<String, SmsTsChargeItemAmount> map = new HashMap<>();
        for (SmsTsChargeItemAmount itemAmount : itemAmountList) {
            map.put(itemAmount.getItemId(), itemAmount);
        }

        // 按照itemList的顺序创建排序后的itemAmountList
        List<SmsTsChargeItemAmount> sortedItemAmountList = new ArrayList<>();
        for (SmsTsChargeItem item : itemList) {
            // 检查是否存在对应的item，若存在则添加到sortedItemList
            SmsTsChargeItemAmount itemAmount = map.get(item.getId());
            sortedItemAmountList.add(itemAmount);
        }

        List<SmsTsChargeItemAmountResp> collect = sortedItemAmountList.stream().map(itemAmount -> {
            SmsTsChargeItemAmountResp resp = new SmsTsChargeItemAmountResp();
            BeanUtils.copyProperties(itemAmount, resp);
            SmsTsFeeCategory category = smsTsFeeCategoryMapper.selectById(itemAmount.getCategoryId());
            if (category != null) {
                resp.setCategoryName(category.getName());
            }
            resp.setLevelName(level.getName());

            SmsTsChargeItem filterItem = itemList.stream().filter(item -> item.getId().equals(itemAmount.getItemId())).collect(Collectors.toList()).get(0);
            if (filterItem != null) {
                resp.setItemName(filterItem.getName());
            }

            return resp;
        }).collect(Collectors.toList());

        return CommonResult.success(collect, collect.size());
    }


}
